require "dgo/tile_map/collision_type"
module MapEditor
  module PaletControler
    class PaletCollisionSetter
      include DGO::TileMap
      def initialize
         arrow_texture = Texture.load($res.tool_path + "res/arrow")
         
         @arrow_width = arrow_texture.width
         @arrow_height = arrow_texture.height
         
         @arrow_textures = []
         
         # generate four direction arrows
         [0, 90, 180, 270].each do |angle|
           t = Texture.new(@arrow_width, @arrow_height)
           t.render_texture(arrow_texture, 0, 0, :angle => angle.degree, :center_x => t.width / 2, :center_y => t.height / 2)
           @arrow_textures << t
         end
         
         @no_arrow_texture = Texture.load($res.tool_path + "res/no_arrow")
      end
      
      def target=(target)
        @target = target
      end
      
      def on_left_down(e)
        @target.sx = ((e.x + @target.scroll_x) / @target.zoomed_grid_width).floor
        @target.sy = ((e.y + @target.scroll_y)/ @target.zoomed_grid_height).floor

        palet_chip = @target.get_palet_chip(@target.sx, @target.sy)

        return if palet_chip.readonly?
        
        dx = (e.x + @target.scroll_x) % @target.zoomed_grid_width
        dy = (e.y + @target.scroll_y) % @target.zoomed_grid_height
        
        [[:up, CollisionType::UP], 
        [:right, CollisionType::RIGHT], 
        [:down, CollisionType::DOWN], 
        [:left, CollisionType::LEFT]].each do |obj|
          # switch arrow of each direction
          if hit_arrow?(obj[0], dx, dy)
            palet_chip.collision_type ^= obj[1]
          end
        end
        
        @target.render
      end
      
      def on_left_up(e)

      end

      def on_right_down(e)

      end

      def on_right_up(e)
      end

      def on_motion(e)
      end

      def on_double_clicked(e)
      
      end
      
      def render(s)
        @target.render_grid(s, @target.grid_width, @target.grid_height)
      end
      
      def hit_arrow?(dir, x, y)
        tx, ty = get_arrow_position(dir)
        return tx <= x && x <= tx + @arrow_width * @target.zoom.half && ty <= y && y <= ty + @arrow_height * @target.zoom.half
      end
      
      def get_arrow_position(dir)
        m_t, m_l, m_b, m_r = @target.zoom, @target.zoom, @target.zoom, @target.zoom

        case dir
          when :up
            return @arrow_width.half * @target.zoom + m_l / 2, m_t
          when :right
            return @arrow_width * @target.zoom + m_l - m_r, @arrow_height.half * @target.zoom + m_t
          when :down
            return @arrow_width.half * @target.zoom + m_l / 2, @arrow_height * @target.zoom + m_t - m_b
          when :left
            return m_l, @arrow_width.half * @target.zoom + m_t
        end

        raise "#{dir} is not defined"
      end

      def render_detail(s)
        m_t, m_l, m_b, m_r = @target.zoom, @target.zoom, @target.zoom, @target.zoom
        [
          [CollisionType::UP, get_arrow_position(:up)], 
          [CollisionType::RIGHT, get_arrow_position(:right)], 
          [CollisionType::DOWN, get_arrow_position(:down)],
          [CollisionType::LEFT, get_arrow_position(:left)]
        ].each_with_index do |obj, no|
        (@target.scroll_x_count..@target.right_count - 1).each do |i|
          (@target.scroll_y_count..@target.bottom_count - 1).each do |j|
            t = @target.get_palet_chip(i, j)
            

              tx = i - @target.scroll_x_count
              ty = j - @target.scroll_y_count

              if (t.collision_type & obj[0]) == 0
                s.render_texture(@arrow_textures[no], tx * @target.zoomed_grid_width + obj[1][0], ty * @target.zoomed_grid_height + obj[1][1], :alpha => 200, :scale_x => @target.zoom.half, :scale_y => @target.zoom / 2.0)
              else
                s.render_texture(@no_arrow_texture, tx * @target.zoomed_grid_width + obj[1][0], ty * @target.zoomed_grid_height + obj[1][1], :alpha => 200, :scale_x => @target.zoom.half, :scale_y => @target.zoom / 2.0)
              end
            end
          end
        end
      end
    end
  end
end